﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Windows.Forms;
using FBEntities.FBObjects;
using XDAFacebook;
using XFControls;
using XFControls.Utils;
using XFControls.XFPanels;
using XFControls.XFPanels.XFPanelItems;
using XFControls.XFPanels.XFPanelModals;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using XFSenseUI.XFItems;

namespace XFItemControls.XFPanels.XFPanelItems
{
    /// <summary>
    /// XFItem that has a Post and a Like button on it
    /// </summary>
    public class XFItemAddComment : XFItemBase
    {
        private bool _commentClicked;
        private FBPost _post;
        private readonly int _height = 40;
        private readonly UpdateEventHandler _userUpdateEvent;

        /// <summary>
        /// Initializes a new instance of the <see cref="XFItemAddComment"/> class.
        /// </summary>
        /// <param name="post">The post.</param>
        public XFItemAddComment(FBPost post)
        {
            _post = post;
            Style = new XFItemStyle
                    {
                        PaddingTop = 2,
                        BackgroundColor = Color.RoyalBlue,
                        TextFont = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Bold),
                        TextColor = Color.White,
                        DashStyleBottom = DashStyle.Dash
                    };

            if (_userUpdateEvent == null)
                _userUpdateEvent = (o, e) =>
                {
                    ResetHeight();
                    Invalidate();
                    var par = Parent as XFPanelList;

                    if (par != null && !par.IsDisposed)
                        par.Damage();
                };

            _post.Updated += _userUpdateEvent;

            if (XFGraphics.GetScreenResolutionNotRotated() == ScreenResolution.QVGA)
                _height /= 2;

            ItemType = XFItemType.ClickableNonChange;
        }

        /// <summary>
        /// Gets the height of the item.
        /// </summary>
        /// <returns></returns>
        public override int GetHeight()
        {
            return _height + Style.PaddingTop + Style.PaddingBottom;
        }

        /// <summary>
        /// Items the paint.
        /// </summary>
        /// <param name="g">The graphics object.</param>
        /// <param name="x">The x coordinate.</param>
        /// <param name="y">The y coordinate.</param>
        public override void ItemPaint(Graphics g, int x, int y)
        {
            base.ItemPaint(g, x, y);
            int width = GetWidth();
            string display = Settings.LocalizationStrings.AddComment;
            string like = _post.PeopleWhoLiked.data.Any(l => l.id.ToString() == XFItemControlUtils.Me.Me.id)
                              ? Settings.LocalizationStrings.Unlike
                              : Settings.LocalizationStrings.Like;

            int xmid = width >> 2;
            int xmidLike = (width >> 2) * 3;

            using (var b = new SolidBrush(Style.TextColor))
            {
                xmid -= (int)(g.MeasureString(display, Style.TextFont).Width / 2);
                g.DrawString(display, Style.TextFont, b, xmid, y + Style.PaddingTop);

                xmidLike -= (int)(g.MeasureString(like, Style.TextFont).Width / 2);
                g.DrawString(like, Style.TextFont, b, xmidLike, y + Style.PaddingTop);
            }
        }

        /// <summary>
        /// Called when [mouse down].
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="y">The y.</param>
        public override void OnMouseDown(int x, int y)
        {
            base.OnMouseDown(x, y);
            int width = Screen.PrimaryScreen.WorkingArea.Width;
            _commentClicked = x <= (width / 2);
        }

        /// <summary>
        /// Gets the click result.
        /// </summary>
        /// <returns></returns>
        public override XFItemClickResult GetClickResult()
        {
            if (_commentClicked)
            {
                var input = new XFPanelTextInput();
                input.AddHistory(GetHistory());

                input.Submitted += CommentSubmit;

                Parent.SetRightPanel(input);
            }
            else
            {
                bool remove = _post.PeopleWhoLiked.data.Any(l => l.id.ToString() == XFItemControlUtils.Me.Me.id);
                string text = remove ? Settings.LocalizationStrings.unlikePost : Settings.LocalizationStrings.likePost;
                IXFModal modal = Parent.ShowModal(XFModal.Bottom, text);
                modal.OnSuccessAction += (o, e) =>
                                             {
                                                 var par = Parent as XFPanelList;
                                                 int loc = par[this];

                                                 var worker = new XFWorkerPostLike(_post, remove);
                                                 var loading = new XFItemLoading(worker, false);

                                                 Invalidate();

                                                 loading.WorkFinished += (ob, ex) =>
                                                                             {
                                                                                 var finishedWorker =
                                                                                     ex.Worker as XFWorkerPostLike;
                                                                                 _post = finishedWorker.ParsedPost;

                                                                                 Invalidate();
                                                                             };

                                                 par.Add(loading, loc);
                                                 loading.DoWork();
                                             };
                modal.State = XFModalState.Expanding;

                return XFItemClickResult.CustomModal;
            }

            return XFItemClickResult.SlideLeft;
        }

        private string[] GetHistory()
        {
            List<string> history = new List<string>();
            if (Parent != null && !Parent.IsDisposed && Parent is XFPanelList)
            {
                foreach (var item in ((XFPanelList)Parent))
                {
                    if (!(item is XFItemPost))
                        continue;

                    var post = (XFItemPost)item;
                    history.Add(post.ToString());
                }
            }
            history.Reverse();
            return history.ToArray();
        }

        private void CommentSubmit(object sender, TextEventArgs args)
        {
            Cursor.Current = Cursors.WaitCursor;
            Application.DoEvents();

            while (true)
            {
                FBComment comment = null;
                try
                {
                    var wrapper = _post.AddComment(args.Text);

                    string html = wrapper.Post();
                    if (!string.IsNullOrEmpty(html))
                    {
                        comment = new FBComment();
                        comment.Parse(JObject.Parse(html));
                        comment.Parse();
                    }
                }
                catch (NullReferenceException)
                {
                    if (MessageBox.Show(Settings.LocalizationStrings.postingProblem,
                                        Settings.LocalizationStrings.tryAgain,
                                        MessageBoxButtons.RetryCancel,
                                        MessageBoxIcon.Exclamation,
                                        MessageBoxDefaultButton.Button1) == DialogResult.Retry)
                        continue;

                    ((XFPanelTextInput)sender).Cancel = true;
                    break;
                }

                var par = Parent as XFPanelList;

                if (!par.IsDisposed && comment != null)
                    par.Invoke(new Action(() =>
                    {
                        var post = new XFItemPost(comment.ToPost());
                        if (par[par.ItemCount - 1] is SenseItem)
                            par.Add(post, par.ItemCount - 2);
                        else
                            par.Add(post);
                    }));
                break;
            }

            Cursor.Current = Cursors.Default;
        }

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        public override void Dispose()
        {
            base.Dispose();
            _post.Updated -= _userUpdateEvent;
        }
    }
}